package com.yc.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yc.common.utils.Encrypt;
import com.yc.entity.*;
import com.yc.service.LogService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yc.common.handler.MapResultHandler;
import com.yc.common.utils.AlyExcelUtil;
import com.yc.common.utils.Encrypt;
import com.yc.entity.User;
import com.yc.exception.CustomException;
import com.yc.mapper.ClassInfoMapper;
import com.yc.mapper.MajorInfoMapper;
import com.yc.service.ClassInfoService;
import com.yc.vo.Result;
import com.yc.vo.StudentAttendanceRecord;
import com.yc.vo.StudentEdit;
import com.yc.vo.StudentInfoAndClassInfo;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.yc.mapper.StudentInfoMapper;
import com.yc.service.StudentInfoService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 学生表;(student_info)表服务实现类
 * @date : 2023-6-28
 */
@Service
public class StudentInfoServiceImpl implements StudentInfoService {
    @Resource
    private StudentInfoMapper studentInfoMapper;

    @Resource
    private RedisTemplate redisTemplate;

    @Autowired
    private LogService logService;

    @Resource
    private ClassInfoService classInfoService;

    @Resource
    private MajorInfoMapper majorInfoMapper;

    @Resource
    private WxUser wxUser;


    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public StudentInfo queryById(Integer id) {
        return studentInfoMapper.selectById(id);
    }

    /**
     * 查询小程序用户Appid
     */
    public StudentInfo selectStuid(String stuid){
        StudentInfo studentInfos = studentInfoMapper.selectByStuid(stuid);
        return studentInfos;
    }

    /**
     * 根据学号查询学生信息
     */
    public Map<String,Object> queryStuBystuid(String stuid){
        Map<String, Object> map = studentInfoMapper.queryByStuid(stuid);
        return map;
    }

    /**
     *  登录时用，验证有无学生信息
     */
    public StudentInfo selectByusername(String stuid){
        StudentInfo studentInfo = studentInfoMapper.selectByUsername(stuid);
        return studentInfo;
    }

    /**
     * 与原密码对比
     * @param stuid
     * @param pwd
     * @return
     */
    public Result querypwdstu(String stuid,String pwd){
        String md5AndSha = Encrypt.md5AndSha(pwd);
        String queryPwd = studentInfoMapper.queryPwd(stuid);
        if (md5AndSha.equals(queryPwd)){
            return Result.success("与原密码一致");
        }else {
            return Result.error("与原密码不一致");
        }
    }

    /**
     * 根据学号查出班级ID
     * @param stuid
     * @return
     */
    public int queriCid(String stuid){
        int classId = studentInfoMapper.queryCid(stuid);
        return classId;
    }

    /**
     * 添加小程序信息根据 stuid
     */
    public void insertByStuid(String appid,String wxpic,String imei,String stuid){
        studentInfoMapper.insertBystuid(appid, wxpic, imei, stuid);
    }

    @ApiOperation("学生登录")
    public int  login(String stuid, String password, int identity, HttpServletRequest request) {
            String pwd = Encrypt.md5AndSha(password);
            LambdaQueryWrapper wrapper1 = Wrappers.<StudentInfo>lambdaQuery().eq(StudentInfo::getStuid,stuid);
            StudentInfo studentInfo =studentInfoMapper.selectOne(wrapper1);
            if(studentInfo ==null){
                //账号不存在请联系管理员,添加账号信息!
                throw new UsernameNotFoundException(" 账号不存在请联系管理员,添加账号信息!");
            }
            QueryWrapper<StudentInfo> wrapper = new QueryWrapper<>();
            wrapper.eq("stuid", stuid).eq("password", pwd);
                StudentInfo studentInfo1 = studentInfoMapper.selectOne(wrapper);
            if (studentInfo1 == null) {
                //账号或密码错误或身份不匹配
                throw new BadCredentialsException(" Invalid username or password ");
            }
            request.getSession().setAttribute("student", studentInfo1);
            request.getSession().setAttribute("stuid", String.valueOf(studentInfo1.getStuid()));
            wxUser.setUsername(stuid);
            redisTemplate.opsForHash().put("STUDENTLOGINTOKEN",String.valueOf(studentInfo1.getStuid()),request.getSession().getId());
            redisTemplate.expire("STUDENTLOGINTOKEN",80, TimeUnit.MINUTES);

            logService.log("用户 "+studentInfo1.getSname()+"登录", studentInfo1.getStuid(),1);
            //user.setPermission(getPermissions(user.getId()));
            return 1;
    }

    /**
     * 分页查询
     *
     * @param studentInfo 筛选条件
     * @param current     当前页码
     * @param size        每页大小
     * @return
     */
    @Override
    public Page<StudentInfo> paginQuery(StudentInfo studentInfo, long current, long size) {
        //1. 构建动态查询条件
        LambdaQueryWrapper<StudentInfo> queryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(studentInfo.getStuid())) {
            queryWrapper.eq(StudentInfo::getStuid, studentInfo.getStuid());
        }
        if (StrUtil.isNotBlank(studentInfo.getPassword())) {
            queryWrapper.eq(StudentInfo::getPassword, studentInfo.getPassword());
        }
        if (StrUtil.isNotBlank(studentInfo.getSname())) {
            queryWrapper.eq(StudentInfo::getSname, studentInfo.getSname());
        }
        if (StrUtil.isNotBlank(studentInfo.getSphone())) {
            queryWrapper.eq(StudentInfo::getSphone, studentInfo.getSphone());
        }
        if (StrUtil.isNotBlank(studentInfo.getAppid())) {
            queryWrapper.eq(StudentInfo::getAppid, studentInfo.getAppid());
        }
        if (StrUtil.isNotBlank(studentInfo.getWxpic())) {
            queryWrapper.eq(StudentInfo::getWxpic, studentInfo.getWxpic());
        }
        if (StrUtil.isNotBlank(studentInfo.getImei())) {
            queryWrapper.eq(StudentInfo::getImei, studentInfo.getImei());
        }
        if (StrUtil.isNotBlank(studentInfo.getSpare())) {
            queryWrapper.eq(StudentInfo::getSpare, studentInfo.getSpare());
        }
        //2. 执行分页查询
        Page<StudentInfo> pagin = new Page<>(current, size, true);
        IPage<StudentInfo> selectResult = studentInfoMapper.selectByPage(pagin, queryWrapper);
        pagin.setPages(selectResult.getPages());
        pagin.setTotal(selectResult.getTotal());
        pagin.setRecords(selectResult.getRecords());
        //3. 返回结果
        return pagin;
    }

    /**
     * 查询该学号是否已有学生
     *
     * @param studentInfo 学生信息
     */
    @Override
    public void selectStudentExists(StudentInfo studentInfo) {
        Integer res = studentInfoMapper.selectStudentExists(studentInfo);
        if (res >= 1) {
            throw new CustomException("0", "该学号已有学生,请检查是否输入正确!");
        }
    }

    /**
     * 修改学生信息
     *
     * @param studentInfo 编辑学生的信息
     * @return 1 成功 0 失败
     */
    @Override
    public int modifyStudent(StudentInfo studentInfo) {
        return studentInfoMapper.modifyStudent(studentInfo);
    }

    /**
     * 分页查询
     *
     * @param page        分页数据
     * @param studentEdit 查询条件
     * @return
     */
    @Override
    public Page<StudentInfoAndClassInfo> selectStudentInfoAndClassInfo(Page<StudentInfoAndClassInfo> page, StudentEdit studentEdit) {
        //redisTemplate.opsForValue().set("line", 0, 5, TimeUnit.MINUTES);
        Page<StudentInfoAndClassInfo> studentInfoAndClassInfoPage = studentInfoMapper.selectStudentInfoAndClassInfo(page, studentEdit);
        if (studentInfoAndClassInfoPage.getRecords() == null) {
            throw new CustomException("0", "查询失败，暂无数据");
        }

        return studentInfoAndClassInfoPage;
    }

    /**
     * 新增数据
     *
     * @param studentInfo 实例对象
     * @return 实例对象
     */
    @Override
    public StudentInfo insert(StudentInfo studentInfo) {
        studentInfoMapper.insert(studentInfo);
        return studentInfo;
    }

    /**
     * 判断是否是默认密码
     * @param stuid
     * @return
     */
    public Result queryPwd(String stuid){
        String pwd = Encrypt.md5AndSha(stuid);
        String Password = studentInfoMapper.queryPwd(stuid);
        if (pwd.equals(Password)==true){
            return Result.success(0);
        }else {
            return Result.success(1);
        }
    }

    /**
     * 查询当天课程
     * @param stuid
     * @param date
     * @return
     */
    public List<Map<String,Object>> querySch(String stuid,String date){
        List<Map<String, Object>> maps = studentInfoMapper.querySch(stuid, date);
        return maps;
    }

    public void updatePwdByStu(String stuid,String pwd){
        String md5AndSha = Encrypt.md5AndSha(pwd);
        studentInfoMapper.updatePwd(md5AndSha,stuid);
    }

    /**
     * 更新数据
     *
     * @param studentInfo 实例对象
     * @return 实例对象
     */
    @Override
    public StudentInfo update(StudentInfo studentInfo) {
        //1. 根据条件动态更新
        LambdaUpdateChainWrapper<StudentInfo> chainWrapper = new LambdaUpdateChainWrapper<StudentInfo>(studentInfoMapper);
        if (StrUtil.isNotBlank(studentInfo.getStuid())) {
            chainWrapper.eq(StudentInfo::getStuid, studentInfo.getStuid());
        }
        if (StrUtil.isNotBlank(studentInfo.getPassword())) {
            chainWrapper.eq(StudentInfo::getPassword, studentInfo.getPassword());
        }
        if (StrUtil.isNotBlank(studentInfo.getSname())) {
            chainWrapper.eq(StudentInfo::getSname, studentInfo.getSname());
        }
        if (StrUtil.isNotBlank(studentInfo.getSphone())) {
            chainWrapper.eq(StudentInfo::getSphone, studentInfo.getSphone());
        }
        if (StrUtil.isNotBlank(studentInfo.getAppid())) {
            chainWrapper.eq(StudentInfo::getAppid, studentInfo.getAppid());
        }
        if (StrUtil.isNotBlank(studentInfo.getWxpic())) {
            chainWrapper.eq(StudentInfo::getWxpic, studentInfo.getWxpic());
        }
        if (StrUtil.isNotBlank(studentInfo.getImei())) {
            chainWrapper.eq(StudentInfo::getImei, studentInfo.getImei());
        }
        if (StrUtil.isNotBlank(studentInfo.getSpare())) {
            chainWrapper.eq(StudentInfo::getSpare, studentInfo.getSpare());
        }
        //2. 设置主键，并更新
        chainWrapper.set(StudentInfo::getId, studentInfo.getId());
        boolean ret = chainWrapper.update();
        //3. 更新成功了，查询最最对象返回
        if (ret) {
            return queryById(studentInfo.getId());
        } else {
            return studentInfo;
        }
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        int total = studentInfoMapper.deleteById(id);
        return total > 0;
    }

    /**
     * 添加学生
     *
     * @param studentInfo 编辑学生的信息
     * @return 0 失败 1 成功
     */
    @Override
    public int addStudent(StudentInfo studentInfo) {
        selectStudentExists(studentInfo);
        studentInfo.setPassword(Encrypt.md5AndSha(studentInfo.getStuid()));
        return studentInfoMapper.addStudent(studentInfo);
    }

    /**
     * 任命为班长或学委
     *
     * @param studentInfo 学生信息
     * @return 1 成功 0 失败
     */
    @Override
    public int appointStudent(StudentInfo studentInfo) {
        if (!"0".equals(studentInfo.getSpare())) {
            studentInfoMapper.removeCom(studentInfo);
        }

        return studentInfoMapper.appointStudent(studentInfo);
    }

    /**
     * 撤职，重新任命
     *
     * @param studentInfo
     * @return
     */
    @Override
    public int removeCom(StudentInfo studentInfo) {
        studentInfoMapper.removeCom(studentInfo);
        return appointStudent(studentInfo);
    }

    /**
     * 下载批量添加学生的模板
     *
     * @param response
     * @return
     * @throws IOException
     */
    public Result<?> downloadTemplate(HttpServletResponse response) throws IOException {
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        org.springframework.core.io.Resource[] resources = resourcePatternResolver.getResources("classpath*:" + File.separator + "static" + File.separator + "file" + File.separator + "addStu.xls");
        org.springframework.core.io.Resource resource = resources[0];
        InputStream inputStream = null;
        OutputStream out = null;
        try {
            //根据文件在服务器的路径读取该文件转化为流
            inputStream = resource.getInputStream();
            //创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            Date date = new Date();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String time = simpleDateFormat.format(date);
            String fileName = "批量添加学生模板-" + time + ".xls";
            //设置文件ContentType类型，这样设置，会自动判断下载文件类型
            response.setContentType("multipart/form-data");
            //设置文件头：最后一个参数是设置下载文件名（设置编码格式防止下载的文件名乱码）
            response.setHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes("UTF-8"), "ISO8859-1"));
            out = response.getOutputStream();
            int b = 0;
            while (b != -1) {
                b = inputStream.read(buffer);
                //写到输出流(out)中
                out.write(buffer, 0, b);
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(1, "下载失败");
        } finally {
            try {
                inputStream.close();
                out.close();
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 上传数据
     *
     * @param inputStream 数据流
     * @return 是否成功
     */
    public int upload(InputStream inputStream, String uid, User user) {
        //先判断是否先前有文件传输失败的情况而导致数据没有传输完毕的情况
        Object history = redisTemplate.opsForValue().get("line");
        int line = history == null ? 0 : (int) history;
        // 获取文件数据源
        List<Map<String, Object>> maps = AlyExcelUtil.excelToShopIdList(inputStream).get(0);
        List<StudentInfo> studentInfoList = new ArrayList<>();
        // 获取所有的班级名
        // 判断是否是辅导员 辅导员只能管理所带的班级
        Map<String, String> classMap = null;
        if (user.getRole().indexOf(2) < 0){
            classMap = classInfoService.selectAllCname(null);
        }else {
            classMap = classInfoService.selectAllCname(user.getUsername());
        }
        // 获得所有的学生
        Map<String, String> studentsMap = selectAllStudent();
        // 判断是否重复上传
        boolean flag = true;

        for (int i = line; i < maps.size(); i++, line++) {
            Map<String, Object> map = maps.get(i);

            String id = (String) map.get("0");
            String stuid = (String) map.get("2");
            String sname = (String) map.get("3");
            String sex = (String) map.get("4");
            String sphone = (String) map.get("5");
            String cname = (String) map.get("1");
            String cid = null;


            //先判断是否有不合规符号
            String regEx = "[_`~!@#$%^&*()+=|{}':;'.<>~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]|\n|\r|\t";
            String regPhone = "^1[3456789]\\d{9}$";



            if (id == null || stuid == null || sname == null || cname == null || (sex != null && !sex.matches(regEx)) ||
                    id.matches(regEx) || stuid.matches(regEx) || sname.matches(regEx)
                    || cname.matches(regEx) || (sphone != null && !sphone.matches(regPhone))) {
                /*传输的过程中出现特殊字符导致数据传输中断，但是改正过来之后再次传输还从首位数据录入信息就显得太慢了
                所以记录错误的位置然后等待下一次传输的时候就从错误的地方开始录入信息
                */
                if (studentInfoList.size() > 0){
                    addStudentList(studentInfoList);
                }
                redisTemplate.opsForValue().set("line", line, 3, TimeUnit.MINUTES);
                return line + 3;
            }

            // 判断是否有这个班级
            //不存在班级 ==> 新建
            // 辅导员不具有创建新班级的权限
            if (!classMap.containsKey(cname)){
                if (user.getRole().indexOf(2) != -1){
                    if (studentInfoList.size() > 0){
                        addStudentList(studentInfoList);
                    }
                    redisTemplate.opsForValue().set("line", line, 3, TimeUnit.MINUTES);
                    throw new CustomException("0", "在第" + (line + 3) + "行,请检查您是否管理这个班级,或者该班级是否存在!");
                }
                ClassInfo classInfo = new ClassInfo();
                String major = cname.substring(0, 2);
                String year = "20" + cname.substring(2, 4);
                classInfo.setCname(cname);
                classInfo.setStatus(1);
                classInfo.setYearnumber(year);
                classInfo.setCreateBy(uid);
                classInfo.setUpdateBy(uid);
                Integer majorId = majorInfoMapper.selectIdByMajor(major);
                classInfo.setMajorid(majorId);
                // 判断是否存在这个专业
                if (majorId == null){
                    redisTemplate.opsForValue().set("line", line, 3, TimeUnit.MINUTES);
                    throw new CustomException("0", "在" + (line + 3) + "行,不存在该专业!");
                }
                classInfoService.insert(classInfo);
                classMap = classInfoService.selectAllCname(null);
            }
            //加入学生的信息
            cid = String.valueOf(classMap.get(cname));
            StudentInfo studentInfo = new StudentInfo();
            studentInfo.setStuid(stuid);
            studentInfo.setPassword(Encrypt.md5AndSha(stuid));
            studentInfo.setSname(sname);
            if ("男性".equals(sex) || "男".equals(sex) ) {
                studentInfo.setSsex(1);
            }else if ( "女性".equals(sex) || "女".equals(sex)){
                studentInfo.setSsex(0);
            }else {
                studentInfo.setSsex(null);
            }
            studentInfo.setSphone(sphone);
            studentInfo.setCid(Integer.parseInt(cid));
            studentInfo.setCreateBy(uid);
            studentInfo.setUpdateBy(uid);
            //Integer res = studentInfoMapper.selectStudentExists(studentInfo);
            if (!studentsMap.containsKey(stuid)) {
                studentInfoList.add(studentInfo);
            }
            if (line % 1000 == 0 && line > 0){
                flag = false;
                addStudentList(studentInfoList);
                studentInfoList = new ArrayList<>();
            }
        }

        if (studentInfoList.size() <= 0 && flag){
            throw new CustomException("0", "文件重复上传");
        }else {
            addStudentList(studentInfoList);
        }
        return 0;
    }

    /**
     * 批量添加学生
     * @param studentInfoList 学生列表
     * @return 成功
     */
    @Override
    public int addStudentList(List<StudentInfo> studentInfoList){
        int res = studentInfoMapper.addStudentList(studentInfoList);
        if (res <= 0){
            throw new CustomException("0", "插入失败!");
        }
        return 1;
    }

    @Override
    public Map<String, String> selectAllStudent() {
        MapResultHandler<String, String> mapResultHandler = new MapResultHandler<>();
        studentInfoMapper.selectAllStudent(mapResultHandler);
        return mapResultHandler.getMappedResults();
    }

    /**
     * 重置学生密码
     * @param id
     */
    @Override
    public void resetPassword(Integer id, String stuid) {
        int result = studentInfoMapper.resetPassword(id, Encrypt.md5AndSha(stuid));
        if (result <= 0){
            throw new CustomException("0", "重置密码失败");
        }
    }

    /**
     * 通过cid查询出班级所在的学生
     * @param cid
     * @return
     */
    @Override
    public List<StudentAttendanceRecord> selectStudentInfoByCid(String scheduleId, String cid){
        List<StudentAttendanceRecord> studentInfoList = studentInfoMapper.selectStudentInfoByCid(scheduleId, cid);
        if (studentInfoList.size() <= 0){
            throw new CustomException("0", "暂无该班级信息!");
        }
        return studentInfoList;
    }

    /**
     * 通过cid查询出班级所在的学生 存入redis
     * @param  uuid redis中的键
     * @param cids 查询条件
     * @return 学生集合
     */
    @Override
    public Object selectStudentsByCid(String uuid, List<String> cids){
        List<StudentAttendanceRecord> result = new ArrayList<>();
        // 如果redis之前存入过学生信息就跳过
        if (redisTemplate.opsForValue().get(uuid) != null){
            return redisTemplate.opsForValue().get(uuid);
        }
        // 班级Id-学号-姓名作为键，status 作为值
        Map<String, String> students = new HashMap();
        for (String id : cids) {
            List<StudentAttendanceRecord> list = studentInfoMapper.selectStudentsByCid(id);
            for (StudentAttendanceRecord student : list) {
                if (student.getLeaveId() != null){
                    student.setStatus(2);
                }
                students.put(student.getCid() + "-" + student.getStuid() + "-" + student.getSname(), student.getStatus() + "-" + student.getLeaveId() + "-" + student.getPic());
                result.add(student);
            }
        }
        if (students.size() <= 0){
            throw new CustomException("0", "暂无信息");
        }
        redisTemplate.opsForValue().set(uuid, students);
        return students;
    }

    /**
     * 通过cid查询出班级所在的学生 存入redis
     * @param  key 暗号
     * @param cids 查询条件
     * @return 学生集合
     */
    @Override
    public Object selectStudentsByCidForWx(String key, List<String> cids){
        // 班级Id-学号-姓名作为键，status 作为值
        Map<String, String> students = new HashMap();
        for (String id : cids) {
            List<StudentAttendanceRecord> list = studentInfoMapper.selectStudentsByCid(id);
            for (StudentAttendanceRecord student : list) {
                if (student.getLeaveId() != null){
                    student.setStatus(2);
                }
                // 如果该键存在，则表明redis中已有缓存，直接返回
                if (students.get(student.getCid() + "-" + student.getStuid() + "-" + student.getSname()) != null){
                    return redisTemplate.opsForValue().get(key);
                }
                students.put(student.getCid() + "-" + student.getStuid() + "-" + student.getSname(), student.getStatus() + "-" + student.getLeaveId() + "-" + student.getPic());
            }
        }
        if (students.size() <= 0){
            throw new CustomException("0", "暂无信息");
        }
        redisTemplate.opsForValue().set(key, students);
        return students;
    }


    /**
     * 根据专业、班级查考勤统计
     * @param stuid
     * @return
     */
    @Override
    public Map<String,Object> selectBystuSum( String stuid){
        List<Map<String, Object>> maps = studentInfoMapper.selectBystuSum(stuid);
        Map<String,Object> data=new HashMap<>();
        // 调用计算分数的方法
        List<Map<String, Object>> calculatedObjects = calculateScores(maps);
        data.put("data",calculatedObjects);
        return data;
    }

    /**
     * 根据班级查考勤统计
     * @param cname
     * @return
     */
    @Override
    public Map<String,Object> selectBystuInfoSum(int pageNum, int pageSize, String cname){
        PageHelper.startPage(pageNum,pageSize);
        List<Map<String, Object>> maps = studentInfoMapper.selectBystuInfoSum(cname);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(maps);
        long total = pageInfo.getTotal(); // 获取总记录数
        Map<String,Object> data=new HashMap<>();
        // 调用计算分数的方法
        List<Map<String, Object>> calculatedObjects = calculateScores(maps);
        data.put("data",calculatedObjects);
        data.put("total",total);
        return data;
    }


    public static List<Map<String, Object>> calculateScores(List<Map<String, Object>> maps) {
        List<Map<String, Object>> calculatedObjects = new ArrayList<>();
        // 遍历每个对象
        for (Map<String, Object> obj : maps) {
            // 旷课
            int absenteeism = ((Number) obj.get("absenteeism")).intValue();
            // 早退
            int leaveEarly = ((Number) obj.get("leave_early")).intValue();
            // 迟到
            int beLate = ((Number) obj.get("be_late")).intValue();
            int finalScore = 50;
            // 计算分数
            int totalScore = (leaveEarly + beLate) / 3 + absenteeism;
            finalScore = finalScore - totalScore;
            // 创建新的包含计算结果的对象
            Map<String, Object> calculatedObj = new HashMap<>(obj);
            calculatedObj.put("final_score", finalScore); // 添加总分数到新对象
            // 将新对象添加到结果列表
            calculatedObjects.add(calculatedObj);
        }
        // 按照 finalScore 属性升序排序
        Collections.sort(calculatedObjects, Comparator.comparingInt(obj -> (int) obj.get("final_score")));
        return calculatedObjects;
    }

}
